<h1>特别注意</h1>

<p><em>这个文档是 session 独立模块，即你单独拿这个模块应用于其他应用中，如果你想在 beego 中使用 session，请查看文档<a href="../mvc/controller/session.md">session 控制</a></em></p>

<h1>session 介绍</h1>

<p>session 模块是用来存储客户端用户，session 模块目前只支持 cookie 方式的请求，如果客户端不支持 cookie，那么就无法使用该模块。</p>

<p>session 模块参考了 <code>database/sql</code> 的引擎写法，采用了一个接口，多个实现的方式。目前实现了 memory、file、Redis 和 MySQL 四种存储引擎。</p>

<p>通过下面的方式安装 session：</p>

<pre><code>go get github.com/astaxie/beego/session
</code></pre>

<h2>session 使用</h2>

<p>首先你必须导入包：</p>

<pre><code>import (
    &quot;github.com/astaxie/beego/session&quot;
)
</code></pre>

<p>然后你初始化一个全局的变量用来存储 session 控制器：</p>

<pre><code>var globalSessions *session.Manager
</code></pre>

<p>接着在你的入口函数中初始化数据：</p>

<pre><code>func init() {
        sessionConfig := &amp;session.ManagerConfig{
    CookieName:&quot;gosessionid&quot;,
    EnableSetCookie: true,
    Gclifetime:3600,
    Maxlifetime: 3600,
    Secure: false,
    CookieLifeTime: 3600,
    ProviderConfig: &quot;./tmp&quot;,
    }
    globalSessions, _ = session.NewManager(&quot;memory&quot;,sessionConfig)
    go globalSessions.GC()
}
</code></pre>

<p>NewManager 函数的参数的函数如下所示</p>

<ol>
    <li>引擎名字，可以是 memory、file、mysql 或 redis。<br /></li>
    <li>一个 JSON 字符串,传入 Manager 的配置信息<br />

        <ol>
            <li>cookieName: 客户端存储 cookie 的名字。<br /></li>
            <li>enableSetCookie,omitempty: 是否开启 SetCookie,omitempty 这个设置<br /></li>
            <li>gclifetime: 触发 GC 的时间。<br /></li>
            <li>maxLifetime: 服务器端存储的数据的过期时间<br /></li>
            <li>secure: 是否开启 HTTPS，在 cookie 设置的时候有 cookie.Secure 设置。<br /></li>
            <li>sessionIDHashFunc: sessionID 生产的函数，默认是 sha1 算法。<br /></li>
            <li>sessionIDHashKey: hash 算法中的 key。<br /></li>
            <li>cookieLifeTime: 客户端存储的 cookie 的时间，默认值是 0，即浏览器生命周期。<br /></li>
            <li>providerConfig: 配置信息，根据不同的引擎设置不同的配置信息，详细的配置请看下面的引擎设置<br /></li>
        </ol></li>
</ol>

<p>最后我们的业务逻辑处理函数中可以这样调用：</p>

<pre><code>func login(w http.ResponseWriter, r *http.Request) {
    sess, _ := globalSessions.SessionStart(w, r)
    defer sess.SessionRelease(w)
    username := sess.Get(&quot;username&quot;)
    if r.Method == &quot;GET&quot; {
        t, _ := template.ParseFiles(&quot;login.gtpl&quot;)
        t.Execute(w, nil)
    } else {
        sess.Set(&quot;username&quot;, r.Form[&quot;username&quot;])
    }
}
</code></pre>

<p>globalSessions 有多个函数如下所示：</p>

<ul>
    <li>SessionStart 根据当前请求返回 session 对象<br /></li>
    <li>SessionDestroy 销毁当前 session 对象<br /></li>
    <li>SessionRegenerateId 重新生成 sessionID<br /></li>
    <li>GetActiveSession 获取当前活跃的 session 用户<br /></li>
    <li>SetHashFunc 设置 sessionID 生成的函数<br /></li>
    <li>SetSecure 设置是否开启 cookie 的 Secure 设置<br /></li>
</ul>

<p>返回的 session 对象是一个 Interface，包含下面的方法</p>

<ul>
    <li>Set(key, value interface{}) error<br /></li>
    <li>Get(key interface{}) interface{}<br /></li>
    <li>Delete(key interface{}) error<br /></li>
    <li>SessionID() string<br /></li>
    <li>SessionRelease()<br /></li>
    <li>Flush() error<br /></li>
</ul>

<h2>引擎设置</h2>

<p>上面已经展示了 memory 的设置，接下来我们看一下其他三种引擎的设置方式：</p>

<ul>
    <li><p>mysql</p>

        <p>其他参数一样，只是第四个参数配置设置如下所示，详细的配置请参考 <a href="https://github.com/go-sql-driver/mysql#dsn-data-source-name">mysql</a>：</p>

        <pre><code>username:password@protocol(address)/dbname?param=value
</code></pre></li>

    <li><p>redis</p>

        <p>配置文件信息如下所示，表示链接的地址，连接池，访问密码，没有保持为空：</p>

        <blockquote>
            <p>注意：若使用redis等引擎作为session backend，请在使用前导入 &lt; _ &ldquo;github.com/astaxie/beego/session/redis&rdquo; &gt;</p>

            <pre><code>    否则会在运行时发生错误，使用其他引擎时也是同理。
</code></pre>
        </blockquote>

        <pre><code>127.0.0.1:6379,100,astaxie
</code></pre></li>

    <li><p>file</p>

        <p>配置文件如下所示，表示需要保存的目录，默认是两级目录新建文件，例如 sessionID 是 <code>xsnkjklkjjkh27hjh78908</code>，那么目录文件应该是 <code>./tmp/x/s/xsnkjklkjjkh27hjh78908</code>：</p>

        <pre><code>./tmp
</code></pre></li>
</ul>

<h2>如何创建自己的引擎</h2>

<p>在开发应用中，你可能需要实现自己的 session 引擎，beego 的这个 session 模块设计的时候就是采用了 interface，所以你可以根据接口实现任意的引擎，例如 memcache 的引擎。</p>

<pre><code>type SessionStore interface {
    Set(key, value interface{}) error //set session value
    Get(key interface{}) interface{}  //get session value
    Delete(key interface{}) error     //delete session value
    SessionID() string                //back current sessionID
    SessionRelease()                  // release the resource &amp; save data to provider
    Flush() error                     //delete all data
}

type Provider interface {
    SessionInit(maxlifetime int64, savePath string) error
    SessionRead(sid string) (SessionStore, error)
    SessionExist(sid string) bool
    SessionRegenerate(oldsid, sid string) (SessionStore, error)
    SessionDestroy(sid string) error
    SessionAll() int //get all active session
    SessionGC()
}
</code></pre>

<p>最后需要注册自己写的引擎：</p>

<pre><code>func init() {
    Register(&quot;own&quot;, ownadaper)
}
</code></pre>
